"""
os 模块提供了很多与操作系统交互的函数
"""
import datetime
import os
from queue import Queue

# 获取当前工作空间
print(os.getcwd())  # /Users/ypykip/codes/python/full-stack-python/document
# 改变当前工作空间
# os.chdir('/Users/ypykip/codes/python/full-stack-python/')
# 运行系统命令
# os.system('mkdir today')
# os.chdir('/Users/ypykip/codes/python/full-stack-python/')
# os.system('rmdir today')

print(dir(os))
# <returns a list of all module functions>
print(len(dir(os)))
# 305
# <returns an extensive manual page created from the module's docstrings>
# print(help(os))

# 日常文件和目录管理任务，shutil模块提供了更易于使用的更高级别的接口：
import shutil

os.system('touch test.txt')
os.system('echo hello world >> test.txt')
# shutil.copyfile('test.txt', 'test_bak.txt')
# os.remove('test.txt')
# os.remove('test_bak.txt')
# shutil.move(os.getcwd() + '/test.txt', "/Users/ypykip/codes/python/full-stack-python/" +'test_bak.txt')
# print(shutil.__all__)
import glob

print(glob.glob('*.txt'))

# 命令行参数
import sys

print(sys.argv[1:])

# 命令行参数
# import argparse
# parser = argparse.ArgumentParser(prog='top', description='Show top lines from each file.')
# parser.add_argument('filenames', nargs="+")
# parser.add_argument("-l","--lines",type=int, default=10)
# args=parser.parse_args()
# print(args)

'''
    sys 模块还有stdin,stdout和stderr的属性。后者对于发出警告和错误消息非常有用，即使在stdout被重定向也
    可以看到它们：
    终止脚本的最直接方法是使用sys.exit()
'''
sys.stderr.write("Warning, log file not found starting a new one \n")

'''
字符串模式匹配
    re模块为高级字符串处理提供正则表达式工具，对于复杂的匹配和操作，正则表达式提供简洁，优化的
    解决方案：
    re
    当只需要简单的功能时，首选字符串方法因为它们跟容易阅读和调试
'''
import re

print(re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest'))
# ['foot', 'fell', 'fastest']
print(re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat'))
# 'cat in the hat'
print("tea for too".replace("too", "two"))

"""
    数学
    math 模块提供对浮点数学的底层C库函数的访问
    random 模块提供了进行随机选择的工具
"""
import math

print(round(math.cos(math.pi / 4), 3))
print(int(math.log(1024, 2)))

import random

print(random.choice(['apple', 'pear', 'banana']))
# 不重复抽样
print(random.sample(range(100), 10))
# random float
print(round(random.random(), 2))
# random integer chosen from range(6)
print(random.randrange(6))

'''
    statistics: 模块计算数值数据的基本统计属性(均值、中位数、方差等)
'''
import statistics

data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
print(statistics.mean(data))  # 平均数
print(statistics.median(data))  # 中位数
print(statistics.variance(data))  # 方差

"""
    互联网访问
    有许多模块可用于访问互联网和处理互联网协议。其中两个简单的urllib.request
    用于从URL检索数据，以及smtplib用于发送邮件：
"""
print("\n==============urlopen==================\n")
from urllib.request import urlopen

with urlopen("http://baidu.com/") as response:
    for line in response:
        line = line.decode('utf-8')
        if line.strip() is not None:
            print(line)
        # if 'EST' in line or 'EDT' in line:
        #     print(line)

print("\n================date===============\n")
"""
    日期和时间
    datetime模块提供了以简单和复杂的方式操作日期和时间的类。虽然支持日期和时间算法，
    但实现的重点是有效的成员提供以进行输出格式化和操作。该模块还支持可感知时区的对象
"""
from datetime import date

now = date.today()
print(now)
datetime.date(2023, 12, 2)
print(now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B."))
'''
    格式符	含义	示例
    %m	月份（两位数）	12
    %d	日期（两位数）	02
    %y	年份（两位数）	03
    %b	缩写的月份名（英文）	Dec
    %Y	四位数的年份	2003
    %A	完整的星期名称	Tuesday
    %B	完整的月份名称     December
'''

birthday = date(2002, 2,15)
age = date.today() - birthday
print(age.days)

birthday = date(1997, 10,10)
age = date.today() - birthday
print(age.days)


"""
    数据压缩
    常见的数据存档和压缩格式由模块直接支持，包括
    zlib,gzip,bz2,lama,zipfile和tarfile
"""
import zlib
s=b'witch which has which witches wrist watch'
print(len(s)) # 41
t = zlib.compress(s)
print(len(t)) # 37
print(zlib.decompress(t))
print(zlib.crc32(s)) # hash 文件唯一码

"""
    性能测试
    timeit 模块可以快速演示在运行效率方面一定的优势
    profile和pstats模块提供了用于较大的代码块中识别时间相关
"""
from timeit import Timer

print(Timer('t=a;a=b;b=t', 'a=1;b=2').timeit())
print(Timer('a,b=b,a', 'a=1;b=2').timeit())


"""
    xmlrpc.client 和 xmlrpc.server 模块使远程过程调用实现了几乎无关紧要的任务。尽管有模块名称，但不需要直接了解或处理xml
    email包是一个用于管理电子邮件的库，包括MIME和其他：基于RFC2822的邮件文档。与stmplib和poplib实际上发送和接收消息不同，电子邮件包
    具有完整的工具集，用于构建或解码复杂的消息结构(包括附件),以及实现互联网编码和标头协议。
    
    json包为解析这种流行的数据交换格式提供了强大的支持。csv模块支持以逗号分隔值格式直接读取和写入文件，这些格式通常由数据库和电子表格支持。
    XML处理由xml.etree.ElementTree,xml.dom和xml.sax支持。这些模块和软件包共同大大简化了Python应用程序和其他工具之间的数据交换。
    
    sqlite3模块是SQLite数据库库的包装器，提供了一个可以使用稍微非标准的SQL语法更新和访问的持久数据库。
    国际化由许多模块支持，包括gettext,locale,以及codecs包。
"""


"""
    格式化输出
    reprlib模块提供了一个定制化版本的repr()函数，用于缩略大型或深层嵌套的容器对象。
    import reprlib
    reprlib.repr(set('supercalifragilisticexpialidocious'))
    # "{'a', 'c', 'd', 'e', 'f', 'g', ...}"
    
    pprint模块提供了更加复杂的打印控制，其输出的内置对象和用户自定义对象能够被解释器直接读取，当输出结果过长而需要折行时，"美化输出机制"会
    添加换行符和缩进，以更加清楚地展示数据结构
"""
import pprint
t = [[[['black','cyan'],'white',['green','red']],[['magenta','yellow'],'blue']]]
pprint.pprint(t)

# [[[['black', 'cyan'], 'white', ['green', 'red']],
# [['magenta', 'yellow'], 'blue']]]

"""
textwrap 模块能够格式化文本段落，以适应给定的屏幕宽度
"""
import textwrap
doc = """The wrap() method is just like fill() except that it returns
... a list of strings instead of one big string with newlines to separate
... the wrapped lines.
"""
print(textwrap.fill(doc, width=99))

import locale

# 设置区域为美国英语
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
value = 1234567.89
formatted_value = locale.currency(value, grouping=True)
print("Formatted as US currency:", formatted_value)

# 更改区域设置为德国德语
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
formatted_value = locale.currency(value, grouping=True)
print("Formatted as German currency:", formatted_value)


"""
    模版：
    string模版包含一个通用的Template类，具有适用于最终用户的简化语法
"""

from string import Template
t = Template("${name} is eating food.")
final_str= t.substitute(name='张三')
print(final_str)


"""
    多线程

"""
# import threading, zipfile
#
# class AsyncZip(threading.Thread):
#     def __init__(self, infile, outfile):
#         threading.Thread.__init__(self)
#         self.infile = infile
#         self.outfile = outfile
#
#     def run(self):
#         f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
#         f.write(self.infile)
#         f.close()
#         print('Finished background zip of:', self.infile)
#
# background = AsyncZip('mydata.txt', 'myarchive.zip')
# background.start()
# print('The main program continues to run in foreground.')
#
# background.join()    # Wait for the background task to finish
# print('Main program waited until background was done.')


"""
    多线程应用面临的主要挑战是，相互协调的多个线程之间需要共享数据或其他资源。为此，threading模块提供了多个同步操作原语，包括线程锁、
    事件、条件变量和信号量。
    尽管这些工具非常强大，但微小的设计错误却可以导致一堆难以复现的问题。因此，实现多任务协作的首选方法是将对资源的所有请求集中到一个线程中，
    然后使用queue模块向该线程提供来自其他线程的请求。应用程序使用Queue对象进行线程之间通信和协调，更易于设计，更易读，更可靠。
"""
import threading
import queue
import time
import random


# 模拟下载文件的函数
def download_file(queue_obj: Queue, thread_name: str):
    while True:
        # 从队列获取任务（文件名）
        file_name = queue_obj.get()
        if file_name == "END":  # 结束信号
            queue_obj.put("END")  # 放回结束信号，让其他线程也能收到
            break

        # 模拟下载过程
        print(f"{thread_name} 开始下载: {file_name}")
        time.sleep(random.uniform(0.5, 1.5))  # 模拟下载耗时
        print(f"{thread_name} 下载完成: {file_name}")
        queue_obj.task_done()  # 标记任务完成


# 创建队列和工作线程
def main():
    task_queue = queue.Queue()
    num_threads = 3  # 3个下载线程

    # 创建工作线程
    threads = []
    for i in range(num_threads):
        thread = threading.Thread(
            target=download_file,
            args=(task_queue, f"线程{i + 1}")
        )
        thread.daemon = True  # 设为守护线程，主线程结束时自动终止
        thread.start()
        threads.append(thread)

    # 向队列添加下载任务
    files_to_download = [f"文件{i}.txt" for i in range(1, 6)]
    for file in files_to_download:
        task_queue.put(file)

    # 添加结束信号
    for _ in range(num_threads):
        task_queue.put("END")

    # 等待所有任务完成
    task_queue.join()
    print("所有文件下载完成！")


# if __name__ == "__main__":
#     main()


"""
    logging模块提供功能齐全且灵活的日志记录系统。在最简单的情况下，日志消息被发送到文件或sys.stderr
"""
import logging as log

log.debug('Debugging information')
log.info('Informational message')
log.warning('Warning: config file %s not found', 'server.conf')
log.error('Error occurred')
log.critical('Critical error -- shutting down')
